﻿#define JSON_FLOAT_SINGLE
#define JSON_SUPPORT_SERIALIZE
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

 /// <summary>
 /// 此类不加命名空间,为所有定义类
 /// </summary>
   public static class ToolsLib
    {
       /// <summary>
       /// 
       /// </summary>
       /// <param name="d"></param>
       /// <returns></returns>
       public static int getEnum(System.Enum d)
       {
           return Convert.ToInt32(d);
       }

        /// <summary>
        /// 转换Json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ToJson<T>(this T o)
        {
            return com.lib.common.MiniJSON.Json.Serialize(o);
        }

        public static int getInt<T>(this T o)
        {
            return Convert.ToInt32(o);
        }

        public static string Decode<T>(this T val)
        {
            return Encoding.UTF8.GetString(Convert.FromBase64String(val.ToString()));
        }

        public static string Encode<T>(this T val)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(val.ToString()));
        }

        public static float getFloat<T>(this T o)
        {
            return Convert.ToSingle(o);
        }

        public static List<Params> getJsonList(string json)
        {
            List<Params> list = new List<Params>();
            var tempList = getJson(json);
            foreach (var m in tempList)
            {
                list.Add(LuaParseJson(m.Replace(@"\", "")));
            }
            return list;
        }

        public static List<string> getJson(string result)
        {
            List<string> mt = new List<string>();
            result = Regex.Unescape(result);
            var tempres = result;
            var kx = tempres.Split('{');

            for (int i = 0; i < kx.Length; i++)
            {
                var lpo = kx[i];

                for (int j = 0; j < lpo.Length; j++)
                {
                    if (lpo[j].ToString().Equals("}"))
                    {
                        string temp = lpo.Substring(0, j + 1);
                        mt.Add("{" + temp);
                    }
                }
            }

            return mt;
        }

        public static Params LuaParseJson(string json)
        {
            Dictionary<string, string> data = new Dictionary<string, string>();
            var value = com.lib.common.MiniJSON.Json.Deserialize(json) as Dictionary<string, object>;
            foreach (var k in value)
            {
                if (k.Value != null)
                {
                    data.Add(k.Key, k.Value.ToString());
                }
                else
                {
                    data.Add(k.Key, "null");
                }
            }
            Params pd = new Params();
            pd.data = data;
            return pd;
        }


    }

   namespace com.lib.common
   {


       /*
    * Copyright (c) 2013 Citybird
    *
    * Based on the JSON parser by Patrick van Bergen
    * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
    *
    * Simplified it so that it doesn't throw exceptions
    * and can be used in Unity iPhone with maximum code stripping.
    *
    */

       // #define JSON_INT_64 

       namespace MiniJSON
       {

           /// <summary>
           /// This class encodes and decodes JSON strings.
           /// Spec. details, see http://www.json.org/
           ///
           /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
           /// All numbers are parsed to doubles.
           /// </summary>
           public static class Json
           {
               /// <summary>
               /// Parses the string json into a value
               /// </summary>
               /// <param name="json">A JSON string.</param>
               /// <returns><![CDATA[
               /// An List<object>, a Dictionary<string, object>, a float, an integer,a string, null, true, or false
               /// ]]></returns>
               //反序列化
               public static object Deserialize(string json)
               {
                   // save the string for debug information
                   if (json == null)
                   {
                       return null;
                   }

                   return Parser.Parse(json);
               }


               sealed class Parser : IDisposable
               {
                   const string WORD_BREAK = "{}[],:\"";

                   public static bool IsWordBreak(char c)
                   {
                       return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
                   }

                   enum TOKEN
                   {
                       NONE,
                       CURLY_OPEN,    // {
                       CURLY_CLOSE,   // }
                       SQUARED_OPEN,  // [
                       SQUARED_CLOSE, // ]
                       COLON,         //:
                       COMMA,         //,
                       STRING,
                       NUMBER,
                       TRUE,
                       FALSE,
                       NULL
                   };

                   StringReader json;

                   Parser(string jsonString)
                   {
                       json = new StringReader(jsonString);
                   }

                   public static object Parse(string jsonString)
                   {
                       using (var instance = new Parser(jsonString))
                       {
                           return instance.ParseValue();
                       }
                   }

                   public void Dispose()
                   {
                       json.Dispose();
                       json = null;
                   }

                   Dictionary<string, object> ParseObject()
                   {
                       Dictionary<string, object> table = new Dictionary<string, object>();

                       // ditch opening brace
                       json.Read();

                       while (true)
                       {
                           switch (NextToken)
                           {
                               case TOKEN.NONE:
                                   return null;
                               case TOKEN.COMMA:
                                   continue;
                               case TOKEN.CURLY_CLOSE:
                                   return table;
                               default:
                                   string name = ParseString();
                                   if (name == null)
                                   {
                                       return null;
                                   }

                                   if (NextToken != TOKEN.COLON)
                                   {
                                       return null;
                                   }
                                   // ditch the colon
                                   json.Read();

                                   // value
                                   table[name] = ParseValue();
                                   break;
                           }
                       }
                   }

                   List<object> ParseArray()
                   {
                       List<object> array = new List<object>();

                       // ditch opening bracket
                       json.Read();

                       bool parsing = true;
                       while (parsing)
                       {
                           TOKEN nextToken = NextToken;

                           switch (nextToken)
                           {
                               case TOKEN.NONE:
                                   return null;
                               case TOKEN.COMMA:
                                   continue;
                               case TOKEN.SQUARED_CLOSE:
                                   parsing = false;
                                   break;
                               default:
                                   object value = ParseByToken(nextToken);

                                   array.Add(value);
                                   break;
                           }
                       }

                       return array;
                   }

                   object ParseValue()
                   {
                       TOKEN nextToken = NextToken;
                       return ParseByToken(nextToken);
                   }

                   object ParseByToken(TOKEN token)
                   {
                       switch (token)
                       {
                           case TOKEN.STRING:
                               return ParseString();
                           case TOKEN.NUMBER:
                               return ParseNumber();
                           case TOKEN.CURLY_OPEN:
                               return ParseObject();
                           case TOKEN.SQUARED_OPEN:
                               return ParseArray();
                           case TOKEN.TRUE:
                               return true;
                           case TOKEN.FALSE:
                               return false;
                           case TOKEN.NULL:
                               return null;
                           default:
                               return null;
                       }
                   }

                   string ParseString()
                   {
                       StringBuilder s = new StringBuilder();
                       char c;

                       // ditch opening quote
                       json.Read();

                       bool parsing = true;
                       while (parsing)
                       {

                           if (json.Peek() == -1)
                           {
                               parsing = false;
                               break;
                           }

                           c = NextChar;
                           switch (c)
                           {
                               case '"':
                                   parsing = false;
                                   break;
                               case '\\':
                                   if (json.Peek() == -1)
                                   {
                                       parsing = false;
                                       break;
                                   }

                                   c = NextChar;
                                   switch (c)
                                   {
                                       case '"':
                                       case '\\':
                                       case '/':
                                           s.Append(c);
                                           break;
                                       case 'b':
                                           s.Append('\b');
                                           break;
                                       case 'f':
                                           s.Append('\f');
                                           break;
                                       case 'n':
                                           s.Append('\n');
                                           break;
                                       case 'r':
                                           s.Append('\r');
                                           break;
                                       case 't':
                                           s.Append('\t');
                                           break;
                                       case 'u':
                                           var hex = new char[4];

                                           for (int i = 0; i < 4; i++)
                                           {
                                               hex[i] = NextChar;
                                           }

                                           s.Append((char)Convert.ToInt32(new string(hex), 16));
                                           break;
                                   }
                                   break;
                               default:
                                   s.Append(c);
                                   break;
                           }
                       }

                       return s.ToString();
                   }

                   object ParseNumber()
                   {
                       string number = NextWord;

                       if (number.IndexOf('.') == -1)
                       {
#if JSON_INT_64
                    long parsedInt;
                    Int64.TryParse(number, out parsedInt);
#else
                           int parsedInt;
                           Int32.TryParse(number, out parsedInt);
#endif
                           return parsedInt;
                       }

#if JSON_FLOAT_SINGLE
                float parsedDouble;
                Single.TryParse(number, out parsedDouble);
#else
                       double parsedDouble;
                       Double.TryParse(number, out parsedDouble);
#endif
                       return parsedDouble;
                   }

                   void EatWhitespace()
                   {
                       while (Char.IsWhiteSpace(PeekChar))
                       {
                           json.Read();
                           if (json.Peek() == -1)
                           {
                               break;
                           }
                       }
                   }

                   char PeekChar
                   {
                       get
                       {
                           return Convert.ToChar(json.Peek());
                       }
                   }

                   char NextChar
                   {
                       get
                       {
                           return Convert.ToChar(json.Read());
                       }
                   }

                   string NextWord
                   {
                       get
                       {
                           StringBuilder word = new StringBuilder();

                           while (!IsWordBreak(PeekChar))
                           {
                               word.Append(NextChar);
                               if (json.Peek() == -1)
                               {
                                   break;
                               }
                           }
                           return word.ToString();
                       }
                   }

                   TOKEN NextToken
                   {
                       get
                       {
                           EatWhitespace();

                           if (json.Peek() == -1)
                           {
                               return TOKEN.NONE;
                           }

                           switch (PeekChar)
                           {
                               case '{':
                                   return TOKEN.CURLY_OPEN;
                               case '}':
                                   json.Read();
                                   return TOKEN.CURLY_CLOSE;
                               case '[':
                                   return TOKEN.SQUARED_OPEN;
                               case ']':
                                   json.Read();
                                   return TOKEN.SQUARED_CLOSE;
                               case ',':
                                   json.Read();
                                   return TOKEN.COMMA;
                               case '"':
                                   return TOKEN.STRING;
                               case ':':
                                   return TOKEN.COLON;
                               case '0':
                               case '1':
                               case '2':
                               case '3':
                               case '4':
                               case '5':
                               case '6':
                               case '7':
                               case '8':
                               case '9':
                               case '-':
                                   return TOKEN.NUMBER;
                           }

                           switch (NextWord)
                           {
                               case "false":
                                   return TOKEN.FALSE;
                               case "true":
                                   return TOKEN.TRUE;
                               case "null":
                                   return TOKEN.NULL;
                           }

                           return TOKEN.NONE;
                       }
                   }
               }


#if JSON_SUPPORT_SERIALIZE

        /// <summary>
        /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
        /// </summary>
        /// <param name="json">A Dictionary<string, object> / List<object></param>
        /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
        public static string Serialize(object obj)
        {
            return Serializer.Serialize(obj);
        }

        sealed class Serializer
        {
            StringBuilder builder;

            Serializer()
            {
                builder = new StringBuilder();
            }

            public static string Serialize(object obj)
            {
                var instance = new Serializer();

                instance.SerializeValue(obj);

                return instance.builder.ToString();
            }

            void SerializeValue(object value)
            {
                IList asList;
                IDictionary asDict;
                string asStr;

                if (value == null)
                {
                    builder.Append("null");
                }
                else if ((asStr = value as string) != null)
                {
                    SerializeString(asStr);
                }
                else if (value is bool)
                {
                    builder.Append((bool)value ? "true" : "false");
                }
                else if ((asList = value as IList) != null)
                {
                    SerializeArray(asList);
                }
                else if ((asDict = value as IDictionary) != null)
                {
                    SerializeObject(asDict);
                }
                else if (value is char)
                {
                    SerializeString(new string((char)value, 1));
                }
                else
                {
                    SerializeOther(value);
                }
            }

            void SerializeObject(IDictionary obj)
            {
                bool first = true;

                builder.Append('{');

                foreach (object e in obj.Keys)
                {
                    if (!first)
                    {
                        builder.Append(',');
                    }

                    SerializeString(e.ToString());
                    builder.Append(':');

                    SerializeValue(obj[e]);

                    first = false;
                }

                builder.Append('}');
            }

            void SerializeArray(IList anArray)
            {
                builder.Append('[');

                bool first = true;

                foreach (object obj in anArray)
                {
                    if (!first)
                    {
                        builder.Append(',');
                    }

                    SerializeValue(obj);

                    first = false;
                }

                builder.Append(']');
            }

            void SerializeString(string str)
            {
                builder.Append('\"');

                char[] charArray = str.ToCharArray();
                foreach (var c in charArray)
                {
                    switch (c)
                    {
                        case '"':
                            builder.Append("\\\"");
                            break;
                        case '\\':
                            builder.Append("\\\\");
                            break;
                        case '\b':
                            builder.Append("\\b");
                            break;
                        case '\f':
                            builder.Append("\\f");
                            break;
                        case '\n':
                            builder.Append("\\n");
                            break;
                        case '\r':
                            builder.Append("\\r");
                            break;
                        case '\t':
                            builder.Append("\\t");
                            break;
                        default:
                            int codepoint = Convert.ToInt32(c);
                            if ((codepoint >= 32) && (codepoint <= 126))
                            {
                                builder.Append(c);
                            }
                            else
                            {
                                builder.Append("\\u");
                                builder.Append(codepoint.ToString("x4"));
                            }
                            break;
                    }
                }

                builder.Append('\"');
            }

            void SerializeOther(object value)
            {
                // NOTE: decimals lose precision during serialization.
                // They always have, I'm just letting you know.
                // Previously floats and doubles lost precision too.
                if (value is float)
                {
                    builder.Append(((float)value).ToString("R"));
                }
                else if (value is int
                  || value is uint
                  || value is long
                  || value is sbyte
                  || value is byte
                  || value is short
                  || value is ushort
                  || value is ulong)
                {
                    builder.Append(value);
                }
                else if (value is double
                  || value is decimal)
                {
                    builder.Append(Convert.ToDouble(value).ToString("R"));
                }
                else
                {
                    SerializeString(value.ToString());
                }
            }
        }

#endif // JSON_SUPPORT_SERIALIZE
           }


       }

   }
 
